package jmine.tec.web.wicket.dao;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import jmine.tec.web.wicket.domain.WebTestEntity;
import junit.framework.Assert;

import org.apache.axis.utils.StringUtils;

import bancosys.tec.persist.dao.BaseDAO;
import bancosys.tec.persist.dao.BeanNotFoundException;
import bancosys.tec.persist.hibernate.page.PagingData;
import bancosys.tec.utils.date.Date;

/**
 * DAO da entidade {@link WebTestEntity}
 * 
 * @author Rafael Volpato
 * @date Oct 14, 2011
 */
public class WebTestEntityDAO extends BaseDAO<WebTestEntity> {

    private static ConcurrentMap<Long, WebTestEntity> entities;

    private static final int TOTAL_ITENS = 100;

    public static void add(WebTestEntity entity) {
        Assert.assertNotNull("cannot save null entities", entity);
        Assert.assertNotNull("cannot 'save' entities with no id", entity.getPk());
        entities.put(entity.getPk(), entity);
    }
    
    static {
        entities = new ConcurrentHashMap<Long, WebTestEntity>();
        long pk = 0L;
        for (int i = 0; i < TOTAL_ITENS; i++) {
            entities.put(++pk,
                    new WebTestEntity(pk, "Nome " + pk, "Mnemonico " + pk, new BigDecimal("1.1").multiply(BigDecimal.valueOf(i)),
                            new Date().addDays(i), new Date().addDays(i+1)));
        }
        
    }
    
    /**
     * Construtor.
     */
    public WebTestEntityDAO() {
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public List<WebTestEntity> findAll() {
        ArrayList<WebTestEntity> entityList = new ArrayList<WebTestEntity>(entities.values());
        PagingData pagingData = this.getPagingService().getPagingData();
        if (pagingData != null) {
            pagingData.setTotalItens(entities.size());
            pagingData.setIncomplete(false);
            int r0 = pagingData.getCurrentPage() * pagingData.getItensPerPage();
            int amount = pagingData.getItensPerPage();
            return entityList.subList(r0, r0 + amount);
        }
        return entityList;
    }

    @Override
    public List<WebTestEntity> findByLikeNaturalKey(String naturalKeyPartial) {
        return this.findByMnemonicoData(naturalKeyPartial, null);
    }

    @Override
    public WebTestEntity findByNaturalKey(Serializable naturalKey) throws BeanNotFoundException {
        if (StringUtils.isEmpty(naturalKey.toString())) {
            throw new BeanNotFoundException(WebTestEntity.class);
        }
        List<WebTestEntity> result = this.findByMnemonicoData(naturalKey.toString(), null);
        if (result.isEmpty()) {
            throw new BeanNotFoundException(WebTestEntity.class);
        }
        return this.findByMnemonicoData(naturalKey.toString(), null).get(0);
    }
    
    /**
     * {@inheritDoc}
     */
    @Override
    public WebTestEntity findByPk(Serializable pk) throws BeanNotFoundException {
        if (entities.containsKey(pk)) {
            return entities.get(pk);
        } else {
            throw new BeanNotFoundException(WebTestEntity.class);
        }
    }

    /**
     * @param mnemonico mnemonico
     * @param data data
     * @return list
     */
    public List<WebTestEntity> findByMnemonicoData(String mnemonico, Date data) {
        List<WebTestEntity> result = new ArrayList<WebTestEntity>();

        for (WebTestEntity entity : entities.values()) {
            boolean matchData = true;
            boolean matchMnemonico = true;

            if (data != null) {
                matchData = data.equals(entity.getData());
            }

            if (mnemonico != null && entity.getMnemonico() != null) {
                matchMnemonico = entity.getMnemonico().toLowerCase().contains(mnemonico.toLowerCase());
            }

            if (matchMnemonico && matchData) {
                result.add(entity);
            }
        }
        return this.paginateInMemory(result);
    }
    
    public List<WebTestEntity> findBy(String mnemonico, Date data, WebTestEntity parent) {
        List<WebTestEntity> result = new ArrayList<WebTestEntity>();

        for (WebTestEntity entity : entities.values()) {
            boolean matchData = true;
            boolean matchMnemonico = true;
            boolean matchParent = true;

            if (data != null) {
                matchData = data.equals(entity.getData());
            }

            if (mnemonico != null && entity.getMnemonico() != null) {
                matchMnemonico = entity.getMnemonico().toLowerCase().contains(mnemonico.toLowerCase());
            }

            if (parent != null) {
                matchParent = entity.getParent() != null && entity.getParent().getMnemonico().equals(parent.getMnemonico());
            }
            
            if (matchMnemonico && matchData && matchParent) {
                result.add(entity);
            }
        }
        return this.paginateInMemory(result);
    }


    private List<WebTestEntity> paginateInMemory(List<WebTestEntity> result) {
        if (this.getPagingService() != null) {
            PagingData pagingData = this.getPagingService().getPagingData();
            if (pagingData != null) {
                pagingData.setTotalItens(result.size());
                pagingData.setIncomplete(false);
                int r0 = pagingData.getCurrentPage() * pagingData.getItensPerPage();
                int amount = pagingData.getItensPerPage();
                int end = r0 + amount;
                end = result.size() < end ? result.size() : end;
                return result.subList(r0, end);
            }
        }
        return result;
    }
}
